package org.example.utils;

/**
 *
 */

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 日期处理
 */
public class DateUtils {
    private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);
    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /** 全时间格式 */
    private static final String FORMAT_FULLTIME = "yyMMddHHmmssSSS";
    /** 全时间格式2 */
    private static final String FORMAT_FULLTIME2 = "yyyyMMdd";
    /** 日期格式 */
    private static final String FORMAT_DATE = "yyyy-MM-dd";
    /** 日期格式 */
    private static final String FORMAT_YEARMONTH = "yyyy-MM";
    /** 纯时间格式 */
    private static final String FORMAT_TIME = "HH:mm:ss";
    /**整点时间格式*/
    private static final String FORMAT_DATETIMEZD = "yyyy-MM-dd HH:00:00";

    /**cron时间格式*/
    private static final String FORMAT_DATETIME_CRON = "ss mm HH dd MM ? yyyy";

    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    /**
     * 得到当前的日期时间字符串
     * @return 日期时间字符串
     */
    public static String getDateTime() {
        Calendar calendar = Calendar.getInstance();
        return getStringFromDate(calendar.getTime(), DATE_TIME_PATTERN);
    }


    /**
     * 得到当前的全时间字符串，包含毫秒
     * @return 日期时间字符串
     */
    public static String getFulltime() {
        Calendar calendar = Calendar.getInstance();
        return getStringFromDate(calendar.getTime(), FORMAT_FULLTIME);
    }
    /**
     * 得到当前的全时间字符串，只到年月日
     * @return 日期时间字符串
     */
    public static String getFulltime_Day(String dataTime) {
        Calendar calendar = Calendar.getInstance();
        if(StringUtils.isNotBlank(dataTime)) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");//注意月份是MM
            try {
                Date date = simpleDateFormat.parse(dataTime);
                return getStringFromDate(date, FORMAT_FULLTIME2);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return getStringFromDate(calendar.getTime(), FORMAT_FULLTIME2);
        }else {
            return getStringFromDate(calendar.getTime(), FORMAT_FULLTIME2);
        }
    }
    /**
     * 得到当前的日期时间字符串
     * @return 日期时间字符串
     */
    public static String getDatetimeW3C() {
        return getDate() + "T" + getTime();
    }

    /**
     * 得到当前的日期时间字符串
     * @return 日期时间字符串
     */
    public static String getDatetimeZd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return getStringFromDate(calendar.getTime(), DATE_TIME_PATTERN);
    }

    /**
     * 得到当前的年月日期字符串
     * @return 年月日期字符串
     */
    public static String getYearMonth() {
        Calendar calendar = Calendar.getInstance();
        return getStringFromDate(calendar.getTime(), FORMAT_YEARMONTH);
    }

    /**
     * 得到当前的日期字符串
     * @return 日期字符串
     */
    public static String getDate() {
        return getDate(Calendar.getInstance());
    }

    /**
     * 得到指定日期的字符串
     * @param calendar  指定的日期
     * @return 日期字符串
     */
    public static String getDate(Calendar calendar) {
        return getStringFromDate(calendar.getTime(), FORMAT_DATE);
    }

    /**
     * 得到当前的纯时间字符串
     * @return 时间字符串
     */
    public static String getTime() {
        Calendar calendar = Calendar.getInstance();
        return getStringFromDate(calendar.getTime(), FORMAT_TIME);
    }


    /**
     * 将日期格式化为指定的字符串
     * @param d 日期
     * @param format    输出字符串格式
     * @return 日期字符串
     */
    public static String getStringFromDate(Date d, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(d);
    }

    /**
     * 根据数字得到中文数字。
     * @param number    数字
     * @return  中文数字
     */
    public static String getChineseNum(String number) {
        String chinese = "";
        int x = Integer.parseInt(number);

        switch (x) {
            case 0:
                chinese = "○";
                break;
            case 1:
                chinese = "一";
                break;
            case 2:
                chinese = "二";
                break;
            case 3:
                chinese = "三";
                break;
            case 4:
                chinese = "四";
                break;
            case 5:
                chinese = "五";
                break;
            case 6:
                chinese = "六";
                break;
            case 7:
                chinese = "七";
                break;
            case 8:
                chinese = "八";
                break;
            case 9:
                chinese = "九";
                break;
            default:
        }
        return chinese;
    }
    /**
     * 得到当前日期的中文日期字符串
     * @return  中文日期字符串
     */
    public static String getChineseDate() {
        return getChineseDate(getDate());
    }

    /**
     * 根据日期值得到中文日期字符串
     * @param date  日期值
     * @return  中文日期字符串
     */
    public static String getChineseDate(String date) {
        if (date.length() < 10) {
            return "";
        } else {
            String year = date.substring(0, 4); // 年
            String month = date.substring(5, 7); // 月
            String day = date.substring(8, 10); // 日
            String y1 = year.substring(0, 1); //年 字符1
            String y2 = year.substring(1, 2); //年 字符1
            String y3 = year.substring(2, 3); //年 字符3
            String y4 = year.substring(3, 4); //年 字符4
            String m2 = month.substring(1, 2); // 月 字符2
            String d1 = day.substring(0, 1); // 日 1
            String d2 = day.substring(1, 2); // 日 2
            String cy1 = getChineseNum(y1);
            String cy2 = getChineseNum(y2);
            String cy3 = getChineseNum(y3);
            String cy4 = getChineseNum(y4);
            String cm2 = getChineseNum(m2);
            String cd1 = getChineseNum(d1);
            String cd2 = getChineseNum(d2);
            String cYear = cy1 + cy2 + cy3 + cy4 + "年";
            String cMonth = "月";

            if (Integer.parseInt(month) > 9) {
                cMonth = "十" + cm2 + cMonth;
            } else {
                cMonth = cm2 + cMonth;
            }

            String cDay = "日";

            if (Integer.parseInt(day) > 9) {
                cDay = cd1 + "十" + cd2 + cDay;
            } else {
                cDay = cd2 + cDay;
            }

            String chineseday = cYear + cMonth + cDay;
            return chineseday;
        }
    }
    /**
     * 根据日期值得到中文日期字符串
     * @param date 给定日期
     * @return 2005年09月23日格式的日期
     */
    public static String getChineseTwoDate(String date) {
        if (date.length() < 10) {
            return "";
        } else {
            String year = date.substring(0, 4); // 年
            String month = date.substring(5, 7); // 月
            String day = date.substring(8, 10); // 日

            return year + "年" + month + "月" + day + "日";
        }
    }
    /**
     * 得到当前日期的星期数 : 例如 '星期一',  '星期二'等
     * @return  当前日期的星期数
     */
    public static String getChineseDayOfWeek() {
        return getChineseDayOfWeek(getDate());
    }

    /**
     * 得到指定日期的星期数
     * @param strDate 指定日期字符串
     * @return  指定日期的星期数
     */
    public static String getChineseDayOfWeek(String strDate) {
        Calendar calendar = getCalendar(strDate);

        int week = calendar.get(Calendar.DAY_OF_WEEK);
        String strWeek = "";

        switch (week) {
            case Calendar.SUNDAY:
                strWeek = "星期日";
                break;
            case Calendar.MONDAY:
                strWeek = "星期一";
                break;
            case Calendar.TUESDAY:
                strWeek = "星期二";
                break;
            case Calendar.WEDNESDAY:
                strWeek = "星期三";
                break;
            case Calendar.THURSDAY:
                strWeek = "星期四";
                break;
            case Calendar.FRIDAY:
                strWeek = "星期五";
                break;
            case Calendar.SATURDAY:
                strWeek = "星期六";
                break;
            default:
                strWeek = "星期一";
                break;
        }

        return strWeek;
    }

    /**
     * 根据规定格式的字符串得到Calendar
     * @param dateString    日期串
     * @return  对应Calendar
     */
    public static Calendar getCalendar(String dateString) {
        Calendar calendar = Calendar.getInstance();
        String[] items = dateString.split("-");
        calendar.set(Integer.parseInt(items[0]), Integer.parseInt(items[1]) - 1, Integer.parseInt(items[2]));
        return calendar;
    }

    /**
     * 将String类型的日期转化成date类型
     *
     * @return
     * @throws java.text.ParseException
     * @throws ParseException
     */
    public static Date stringToDate(String dateString, String pattern) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.parse(dateString);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 计算距离现在多久，非精确
     *
     * @param date
     * @return
     */
    public static String getTimeBefore(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        } else if (hour > 0) {
            r += hour + "小时";
        } else if (min > 0) {
            r += min + "分";
        } else if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }

    /**
     * 计算距离现在多久，精确
     *
     * @param date
     * @return
     */
    public static String getTimeBeforeAccurate(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        }
        if (hour > 0) {
            r += hour + "小时";
        }
        if (min > 0) {
            r += min + "分";
        }
        if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }

    /**
     * 计算激励现在多久   小时格式 （11.11小时）
     * @return
     * @throws ParseException
     */
    public static String stringToNum(String time) throws ParseException {
        Date dateTime = stringToDate(time, DATE_TIME_PATTERN);
        Date now = new Date();
        long l = now.getTime() - dateTime.getTime();
        String d = null;
        if (l > 0) {
            d = String.valueOf(((double) l) /  (1000 * 60 * 60));
        }
        if ( d != "" && d != null ) {
            d = d.substring(0, d.indexOf(".") + 3);
        }
        return d;
    }
    /**
     * 将指定格式的字符串格式化为日期
     * @param s 字符串内容
     * @param format    字符串格式
     * @return 日期
     */
    public static Date getDateFromString(String s, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.parse(s);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 某日期（带时间）加上时间间隔得到另外一个日期 （带时间）
     *
     * @param datetime      需要调整的日期（带时间）
     * @param space         调整间隔
     * @param type          调整类型
     * @return              调整后的日期（带时间）
     */
    public static String getCertainDatetime(String datetime, int space, String type) {
        Date curDate = getDateFromString(datetime, DATE_TIME_PATTERN);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(curDate);
        if(type.equals("MONTH")){
            calendar.add(Calendar.MONTH, space);
        }else if(type.equals("DATE")){
            calendar.add(Calendar.DATE, space);
        }else if(type.equals("HOUR")){
            calendar.add(Calendar.HOUR, space);
        }else if(type.equals("MINUTE")){
            calendar.add(Calendar.MINUTE, space);
        }
        return getStringFromDate(calendar.getTime(), DATE_TIME_PATTERN);
    }

    public static String getCronExpression(String datetime){
        Date curDate = getDateFromString(datetime, DATE_TIME_PATTERN);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(curDate);
        return getStringFromDate(calendar.getTime(), DATE_TIME_PATTERN);
    }

    /***
     * 计算时间差  以分钟为单位
     * @throws ParseException
     * 如果其中一个为空，则传回空字符串
     */
    public static String startAndEnd(String startTime,String endTime){
        if (StringUtils.isNotBlank(startTime)&&StringUtils.isNotBlank(endTime)) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(getDateFromString(startTime, DATE_TIME_PATTERN));
            long time1 = cal.getTimeInMillis();
            cal.setTime(getDateFromString(endTime, DATE_TIME_PATTERN));
            long time2 = cal.getTimeInMillis();
            long between_minute = (time2 - time1) / (1000 * 60);
            return String.valueOf(between_minute);
        }
        return " ";
    }

    /**
     * 格式化日期字符串
     * @param s
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String formatDateString(String s ,String pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date = sdf.parse(s);
        return sdf.format(date);
    }



}

